Richer IDL generation with compilation #1927
Closed
+476
−1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If we have a, for example,
Program<'info, SomeProgram>
constraint in the accounts, we know that the account with the SomeProgram::id() pubkey needs to be passed in, but we're not able to leverage this information from the clients because it's not encoded within the IDL (aside from the hack in anchor ts where we match by account name only for specific accounts).The reason this is not possible currently is because the IDL generation works by parsing the program source code which gives it access to the TokenStream (basically AST) but parsing the actual program ID of the referenced program from this is, to say the least, not practical.
In order to go around this, in this POC I've taken a slightly different approach. Instead of just parsing the program source and outputting the generated IDL, I've l codegened an intermediate binary which is then compiled and run to to print out the IDL. The benefit of this approach is that now instead of only having access to the AST, we can also evaluate expressions within the program source.
So, referring to the the above example, with the binary we can do:
and when this is executed it will output
giving the possibility of encoding more information in the IDL.
Expression evaluation is not only useful for the Program constraint, but also for seeds, seeds::program, etc. Essentially, anything that does rely on an input to the ix call (ix arg, passed account, or account data) we can now evaluate and put in the IDL.
Here's a more detailed example that was generated by this POC for a test program, and this is the IDL it generates (I've generated only the instructions field here for the POC but this would output the full IDL).
Notes:
TODO:
Sysvar
,address = <>
, andseeds::program = <>
Consideration:
The POC command I've implemented generates the binary in the program source directory which is probably not ideal because it pollutes users codebase. We probably want to generate it in the
.anchor
directory or similar.In that case we'd also need to copy the program's Cargo.toml in there to have the same dependencies.
@armaniferrante let me know if this approach is valid so I can finish this up.